﻿using System;

namespace Ecobee.Net
{
	/// <summary>
	/// Represents Ecobee API errors that occur during application execution.
	/// </summary>
	public abstract class ResponseCodeException : EcobeeException, IResponseCodeException
	{
		private int _responseCode = 0;

		/// <summary>
		/// Initializes a new instance of the Ecobee.Net.ResponseCodeException class.m
		/// </summary>
		public ResponseCodeException()
			: base()
		{
		}

		/// <summary>
		/// Initializes a new instance of the System.Exception class with a specified
		/// error message.
		/// </summary>
		/// <param name="message">The error message that explains the reason for the exception.</param>
		public ResponseCodeException(string message)
			: base(message)
		{
		}

		/// <summary>
		/// Initializes a new instance of the System.Exception class with a specified
		/// error message and response code.
		/// </summary>
		/// <param name="responseCode">The ecobee API response code that this exception represents.</param>
		/// <param name="message">The error message that explains the reason for the exception.</param>
		public ResponseCodeException(int responseCode, string message)
			: base(message)
		{
			this.ResponseCode = responseCode;
		}

		/// <summary>
		/// Initializes a new instance of the Ecobee.Net.ResponseCodeException class with a specified
		/// error message and a reference to the inner exception that is the cause of
		/// this exception.
		/// </summary>
		/// <param name="innerException">The exception that is the cause of the current exception, 
		/// or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
		/// <param name="message">The error message that explains the reason for the exception.</param>
		public ResponseCodeException(Exception innerException, string message)
			: base(message, innerException)
		{
		}

		/// <summary>
		/// Initializes a new instance of the Ecobee.Net.ResponseCodeException class with a specified
		/// error message, response code and a reference to the inner exception that is the cause of
		/// this exception.
		/// </summary>
		/// <param name="responseCode">The ecobee API response code that this exception represents.</param>
		/// <param name="innerException">The exception that is the cause of the current exception, 
		/// or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
		/// <param name="message">The error message that explains the reason for the exception.</param>
		public ResponseCodeException(int responseCode, Exception innerException, string message)
			: base(message, innerException)
		{
			this.ResponseCode = responseCode;
		}

		/// <summary>
		/// Initializes a new instance of the System.Exception class with a specified
		/// error message. Replaces the format item in a specified string with the 
		/// string representation of a corresponding object in a specified array.
		/// </summary>
		/// <param name="format">A composite format string</param>
		/// <param name="args">An object array that contains zero or more objects to format.</param>
		public ResponseCodeException(string format, params object[] args)
			: base(string.Format(format, args))
		{
		}

		/// <summary>
		/// Initializes a new instance of the Ecobee.Net.ResponseCodeException class with a specified
		/// error message and a reference to the inner exception that is the cause of
		/// this exception. Replaces the format item in a specified string with the string 
		/// representation of a corresponding object in a specified array.
		/// </summary>
		/// <param name="innerException">The exception that is the cause of the current exception, or 
		/// a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
		/// <param name="format">A composite format string</param>
		/// <param name="args">An object array that contains zero or more objects to format.</param>
		public ResponseCodeException(Exception innerException, string format, params object[] args)
			: base(string.Format(format, args), innerException)
		{
		}

		/// <summary>
		/// Initializes a new instance of the System.Exception class with a specified
		/// error message and response code. Replaces the format item in a specified string with the 
		/// string representation of a corresponding object in a specified array.
		/// </summary>
		/// <param name="responseCode">The ecobee API response code that this exception represents.</param>
		/// <param name="format">A composite format string</param>
		/// <param name="args">An object array that contains zero or more objects to format.</param>
		public ResponseCodeException(int responseCode, string format, params object[] args)
			: base(string.Format(format, args))
		{
			this.ResponseCode = responseCode;
		}

		/// <summary>
		/// Initializes a new instance of the Ecobee.Net.ResponseCodeException class with a specified
		/// error message, response code and a reference to the inner exception that is the cause of
		/// this exception. Replaces the format item in a specified string with the string 
		/// representation of a corresponding object in a specified array.
		/// </summary>
		/// <param name="responseCode">The ecobee API response code that this exception represents.</param>
		/// <param name="innerException">The exception that is the cause of the current exception, or a 
		/// null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
		/// <param name="format">A composite format string</param>
		/// <param name="args">An object array that contains zero or more objects to format.</param>
		public ResponseCodeException(int responseCode, Exception innerException, string format, params object[] args)
			: base(string.Format(format, args), innerException)
		{
			this.ResponseCode = responseCode;
		}

		/// <summary>
		/// Gets the ecobee API response code that this exception represents.
		/// </summary>
		public int ResponseCode
		{
			get
			{
				return _responseCode;
			}
			internal set
			{
				_responseCode = value;
			}
		}

		/// <summary>
		/// Gets an array of Ecobee.Net.ResponseCodeException objects that represents the possible
		/// status response codes from the API.
		/// </summary>
		public static ResponseCodeException CreateResponseCodeException(int responseCode, Exception innerException)
		{
			ResponseCodeException returnValue = null;

			switch (responseCode)
			{
				case 1:
					returnValue = new AuthenticationFailed(innerException);
					break;
				case 2:
					returnValue = new NotAuthorized(innerException);
					break;
				case 3:
					returnValue = new ProcessingError(innerException);
					break;
				case 4:
					returnValue = new SerializationError(innerException);
					break;
				case 5:
					returnValue = new InvalidRequestFormat(innerException);
					break;
				case 6:
					returnValue = new TooManyThermostats(innerException);
					break;
				case 7:
					returnValue = new ValidationError(innerException);
					break;
				case 8:
					returnValue = new InvalidFunction(innerException);
					break;
				case 9:
					returnValue = new InvalidSelection(innerException);
					break;
				case 10:
					returnValue = new InvalidPage(innerException);
					break;
				case 11:
					returnValue = new AuthenticationFailed(innerException);
					break;
				case 12:
					returnValue = new AuthenticationFailed(innerException);
					break;
				case 13:
					returnValue = new AuthenticationFailed(innerException);
					break;
				case 14:
					returnValue = new AuthenticationFailed(innerException);
					break;
				case 15:
					returnValue = new AuthenticationFailed(innerException);
					break;
			}

			return returnValue;
		}
	}
}
